﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Threading;
using System.Web;

namespace $safeprojectname$.Storage
{
    /// <summary>
    ///     Session abstraction
    /// </summary>
    public class SessionStorage : ISessionStorage
    {
        #region members
        static IDictionary<string, object> _session;
        HttpContextBase _httpContextBase;
        HttpContext _httpContext;
        #endregion members

        #region constructor
        public SessionStorage() { }
        public SessionStorage(HttpContextBase context)
        {
            if (context.Is())
            {
                _httpContextBase = context;
            }
        }
        public SessionStorage(HttpContext context)
        {
            if (context.Is())
            {
                _httpContext = context;
            }
        }
        #endregion constructor

        #region ISessionStorage Members
        public virtual object this[string key]
        {
            get
            {
                // ASP.NET MVC world
                if (HttpContextBase.Is()
                    && HttpContextBase.Session.Is())
                {
                    return HttpContextBase.Session[UniqueIdentifier(key)];
                }
                // ASP.NET
                else if (HttpContext.Is()
                && HttpContext.Session.Is())
                {
                    return HttpContext.Session[UniqueIdentifier(key)];
                }
                // console app...
                if (Session.ContainsKey(UniqueIdentifier(key)))
                {
                    return Session[UniqueIdentifier(key)];
                }
                return null;
            }
            set
            {
                // ASP.NET MVC world
                if (HttpContextBase.Is()
                  && HttpContextBase.Session.Is())
                {
                    HttpContextBase.Session[UniqueIdentifier(key)] = value;
                }
                // ASP.NET
                else if (HttpContext.Is()
                && HttpContext.Session.Is())
                {
                    HttpContext.Session[UniqueIdentifier(key)] = value;
                }
                // console app...
                else
                {
                    Session[UniqueIdentifier(key)] = value;
                }
            }
        }
        public virtual void Remove(string key)
        {
            // ASP.NET MVC
            if (HttpContextBase.Is()
                 && HttpContextBase.Session.Is())
            {
                HttpContextBase.Session.Remove(UniqueIdentifier(key));
            }
            // ASP.NET
            else if (HttpContext.Is()
                && HttpContext.Session.Is())
            {
                HttpContext.Session.Remove(UniqueIdentifier(key));
            }
            // console app...
            else
            {
                if (Session.ContainsKey(UniqueIdentifier(key)))
                {
                    Session.Remove(UniqueIdentifier(key));
                }
            }
        }

        public virtual void Clear()
        {
            if (HttpContextBase.Is()
                && HttpContextBase.Session.Is())
            {
                HttpContextBase.Session.Clear();
            }
            else if (HttpContext.Is()
                && HttpContext.Session.Is())
            {
                HttpContext.Session.Clear();
            }
            else
            {
                Session.Clear();
            }

        }
        #endregion

        #region properties
        /// <summary>
        ///     This will provide the safe Session usage.
        ///     Every key is also decorated with the current user Identity.
        ///     Stolen SessionId will not work with different identitiy
        /// </summary>
        /// <param name = "key"></param>
        /// <returns></returns>
        protected virtual string UniqueIdentifier(string key)
        {
            return Thread.CurrentPrincipal.Identity.Name + "|" + key;
        }

        protected virtual HttpContextBase HttpContextBase
        {
            get { return _httpContextBase; }
            set { _httpContextBase = value; }
        }

        protected virtual HttpContext HttpContext
        {
            get { return _httpContext; }
            set { _httpContext = value; }
        }

        protected static IDictionary<string, object> Session
        {
            get { return _session ?? (_session = new Dictionary<string, object>()); }
        }
        #endregion properties

    }
}